Because IPython supports HTML and JavaScript representations of Python objects, it is possible to leverage the power of d3.js, even without using the new Widget architecture. These examples help to clarify the differences between regular HTML/JavaScript output and the new Widgets:
Regular HTML/JavaScript output in the notebook is put on the page a single time and subsequently cannot communicate with the backend kernel
Widgets can communicate with the backend kernel bidirectionally at any time after being rendered on the page.
One of the central benefits of using regular HTML/JavaScript output is that the resulting visualizations will work on http://nbviewer.ipython.org for IPython 2.0.
We are working on enabling Widgets on http://nbviewer.ipython.org, but it will probably be another 6 months.
Here is a simple example from the d3 website, which shows how we can use d3 directly in the Notebook.
First, let's create a div
for a d3 visualization and define some CSS styles:
In [1]:
%%html
<div id="d3-example"></div>
<style>
.node {stroke: #fff; stroke-width: 1.5px;}
.link {stroke: #999; stroke-opacity: .6;}
</style>
Now let's run the JavaScript code for a d3 example using the %%javascript
magic. Note, this is pulling the data (miserables.json
) from a local file sitting in the data
directory next to this notebook and using the above defined div
and CSS.
In [2]:
%%javascript
require.config({paths: {d3: "http://d3js.org/d3.v3.min"}});
require(["d3"], function(d3) {
var width = 600,
height = 400;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
var svg = d3.select("#d3-example").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("data/miserables.json", function(error, graph) {
force.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", function(d) { return color(d.group); })
.call(force.drag);
node.append("title")
.text(function(d) { return d.name; });
force.on("tick", function() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
});
});
Matplotlib is a mature visualization library for Python. When using matplotlib in the notebook it usually produces PNG, JPEG or PDF output.
mpld3 is a recently created Python library that converts matplotlib Figure
objects to d3 based visualizations that the notebook can display.
In [3]:
%matplotlib inline
import numpy as np
from matplotlib import pyplot as plt
from mpld3 import enable_notebook, plugins
enable_notebook()
In [7]:
from sklearn.datasets import load_iris
data = load_iris()
X = data.data
y = data.target
# dither the data for clearer plotting
X += 0.1 * np.random.random(X.shape)
fig, ax = plt.subplots(4, 4, sharex="col", sharey="row", figsize=(8, 8))
fig.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95,
hspace=0.1, wspace=0.1)
for i in range(4):
for j in range(4):
ax[3 - i, j].scatter(X[:, j], X[:, i],
c=y, s=40, alpha=0.3)
# remove tick labels
for axi in ax.flat:
for axis in [axi.xaxis, axi.yaxis]:
axis.set_major_formatter(plt.NullFormatter())
# add a reset() button
plugins.connect(fig, plugins.ResetButton())
plt.show()
Plotly is a web-based data analysis and plotting tool that has IPython integration and uses d3 for its visualizations.
In [5]:
import plotly
py = plotly.plotly('IPython.Demo', '1fw3zw2o13')
nr = np.random
In [6]:
distributions = [nr.uniform, nr.normal , lambda size: nr.normal(0, 0.2, size=size),
lambda size: nr.beta(a=0.5, b=0.5, size=size),
lambda size: nr.beta(a=0.5, b=2, size=size)]
names = ['Uniform(0,1)', 'Normal(0,1)', 'Normal(0, 0.2)', 'beta(a=0.5, b=0.5)', 'beta(a=0.5, b=2)']
boxes = [{'y': dist(size=50), 'type': 'box', 'boxpoints': 'all', 'jitter': 0.5, 'pointpos': -1.8,
'name': name} for dist, name in zip(distributions, names)]
layout = {'title': 'A few distributions',
'showlegend': False,
'xaxis': {'ticks': '', 'showgrid': False, 'showline': False},
'yaxis': {'zeroline': False, 'ticks': '', 'showline': False},
}
py.iplot(boxes, layout = layout, filename='Distributions', fileopt='overwrite', width=1000, height=650)
Out[6]:
In [ ]: